/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod;

//import Inspur.Gsp.Caf.Generator.Utils.*;
//import Inspur.Gsp.Cef.Repository.*;
//import Inspur.Gsp.Cef.Repository.ReaderWriter.*;
//import Microsoft.CodeAnalysis.*;
//import Microsoft.CodeAnalysis.CSharp.*;
//import Microsoft.CodeAnalysis.CSharp.Syntax.*;

import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.cef.api.attr.PropertyGetAtrribute;
import com.inspur.edp.cef.designtime.api.IGspCommonDataType;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.element.GspAssociationKey;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.cef.gencommon.ReflectionUtils;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.EntityGeneratorContext;
import com.inspur.edp.cef.generator.overall.CefGenerator;
import com.inspur.edp.cef.generator.overall.CefGeneratorContext;
import com.inspur.edp.cef.generator.overall.GeneratorUtil;
import com.inspur.edp.cef.generator.overall.Utils;
import com.inspur.edp.cef.generator.repository.RepositoryGenUtil;
import com.inspur.edp.cef.repository.adaptor.BaseEntityAdaptor;
import com.inspur.edp.cef.repository.adaptor.DataTypeAdapter;
import com.inspur.edp.cef.repository.adaptor.EntityRelationalAdaptor;
import com.inspur.edp.cef.repository.assembler.AssociationInfo;
import com.inspur.edp.cef.repository.readerwriter.CefMappingReader;
import com.inspur.edp.cef.repository.repo.BaseRootRepository;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.udt.entity.IUdtData;
import org.eclipse.jdt.core.dom.*;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

//
//     private DepartInfo getDeptIDAssInfo(ICefReader reader)
//     {
//     DepartInfo info =new DepartInfo();
//       Dictionary<string, string> mapping =new Dictionary<string, string>();
//       mapping.Add("Code1","Code");
//       mapping.Add("Name1","Name");
//       mapping.Add("TreeInfo1","TreeInfo");
//       CefMappingReader mappingreader = new CefMappingReader(mapping, reader);
//       var adapter=( getAssociation("DeptID").RefRepository as BaseRootRepository).getEntityDac("").GetEntityAdaptor();
//     info.Code= adapter.readproperty("Code",reader);
//     info.Code= ( getAssociation("DeptID").RefRepository as BaseRootRepository).getEntityDac("DepartmentInfo").GetEntityAdaptor().readproperty("Name",reader);
//     info.Code= ( getAssociation("DeptID").RefRepository as BaseRootRepository).getEntityDac("DepartmentInfo").GetEntityAdaptor().readproperty("TreeInfo",reader);
//     return info;
//     }
//
public class EntityCreateAssocationDefMethodGenerator extends BasePropertyCreateDefMethodGenerator {
	private String propertyClassName;
	private String propertyName;
	private IGspCommonDataType gspCommonDataType;
	private IGspCommonField gspCommonField;
	private GspAssociation associationInfo;
	private CefGeneratorContext cefGeneratorContext;
	private static final String varName = "assValue";
	public static final String varMapping = "mapping";
	private static final String varAdapter = "adapter";

	public EntityCreateAssocationDefMethodGenerator(CefGeneratorContext cefGeneratorContext, IGspCommonDataType gspCommonDataType, IGspCommonField gspCommonField, GspAssociation associationInfo, String propertyClassName, String propertyName) {
		this.cefGeneratorContext = cefGeneratorContext;
		this.gspCommonDataType = gspCommonDataType;
		this.gspCommonField = gspCommonField;
		this.associationInfo = associationInfo;
		this.propertyClassName = propertyClassName;
		this.propertyName = propertyName;
	}

	@Override
	protected String getMethodName() {
		return getAssPropertyValueMethodName(propertyName);
	}

	@Override
	protected TypeInfo getReturnType() {
		TypeInfo info =new TypeInfo(propertyClassName);
		if(gspCommonField.getIsUdt()){
			info.setUseFullName(true);
		}
		return info;
	}
	public IGspCommonField getGspCommonField() {
		return gspCommonField;
	}

	public void setGspCommonField(IGspCommonField gspCommonField) {
		this.gspCommonField = gspCommonField;
	}



	@Override
	protected Block buildMethodBody() {
		ArrayList<Statement> statements = new ArrayList<>();
		addImport(CefMappingReader.class.getTypeName());
		addImport(BaseRootRepository.class.getTypeName());
		addNewAssoInfoStatement(statements, varName);
		addInitMappingStatement(ast, statements, gspCommonField.getLabelID(), varMapping);
		addNewMappingReaderStatement(ast, statements, getMappingReader(propertyName), varMapping);
		addNewAdapterStatement(ast, statements, propertyName, varAdapter, associationInfo.getRefObjectCode());
		addImport(EntityRelationalAdaptor.class.getTypeName());

		addSetInfoPropertyStatemens(ast, statements, associationInfo, gspCommonField, this.propertyClassName, propertyName, gspCommonDataType, cefGeneratorContext);
		addReturnInfoStatement(statements);
		Block block = ast.newBlock();
		block.statements().addAll(statements);
		return block;
	}

	private void addReturnInfoStatement(ArrayList<Statement> statements) {
		ReturnStatement returnStatement = ast.newReturnStatement();

		returnStatement.setExpression(ast.newSimpleName(varName));
		statements.add(returnStatement);
	}

	private void addNewAssoInfoStatement(ArrayList<Statement> statements, String varName) {
		VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
		variableDeclarationFragment.setName(ast.newSimpleName(varName));

		ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
		classInstanceCreation.setType(ast.newSimpleType(ast.newName(propertyClassName)));
		variableDeclarationFragment.setInitializer(classInstanceCreation);

		VariableDeclarationStatement variableDeclarationStatement = ast.newVariableDeclarationStatement(variableDeclarationFragment);
		variableDeclarationStatement.setType(ast.newSimpleType(ast.newName(propertyClassName)));
		statements.add(variableDeclarationStatement);
	}

//	private IGspCommonField getAssoField(GspAssociation associationInfo){
//		String sourceElementId = "";
//		for(GspAssociationKey key: associationInfo.getKeyCollection()){
//			sourceElementId = key.getSourceElement();
//			break;
//		}
//		for(IGspCommonField gspCommonField: this.g.getContainElements()){
//			if(gspCommonField.getID().equals(sourceElementId)){
//				return gspCommonField;
//			}
//		}
//		return null;
//	}


	public static void addInitMappingStatement(AST ast, ArrayList<Statement> statements, String propertyName, String varMappingName) {
		MethodInvocation methodInvocation = ast.newMethodInvocation();
		methodInvocation.setName(ast.newSimpleName("get" + propertyName + "AssoDBMapping"));

		VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
		variableDeclarationFragment.setName(ast.newSimpleName(varMappingName));
		variableDeclarationFragment.setInitializer(methodInvocation);

		ParameterizedType parameterizedType = ast.newParameterizedType(ast.newSimpleType(ast.newSimpleName("HashMap")));
		parameterizedType.typeArguments().add(ast.newSimpleType(ast.newSimpleName("String")));
		parameterizedType.typeArguments().add(ast.newSimpleType(ast.newSimpleName("String")));
		VariableDeclarationStatement variableDeclarationStatement = ast.newVariableDeclarationStatement(variableDeclarationFragment);
		variableDeclarationStatement.setType(parameterizedType);
		statements.add(variableDeclarationStatement);
	}

//	public static void addInitMappingStatement(AST ast, ArrayList<Statement> statements, AssociationInfo associationInfo, String varMappingName) {
//		addNewMappingStatement(ast, statements, varMappingName);
//		addSetMappingItemsStatements(ast, statements, associationInfo, varMappingName);
//	}

	private static void addNewMappingStatement(AST ast, ArrayList<Statement> statements, String varMapping) {
		VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
		variableDeclarationFragment.setName(ast.newSimpleName(varMapping));

		ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
		ParameterizedType parameterizedType1 = ast.newParameterizedType(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(HashMap.class).getType(ast));
		parameterizedType1.typeArguments().add(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(String.class).getType(ast));
		parameterizedType1.typeArguments().add(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(String.class).getType(ast));
		classInstanceCreation.setType(parameterizedType1);

		variableDeclarationFragment.setInitializer(classInstanceCreation);

		ParameterizedType parameterizedType = ast.newParameterizedType(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(HashMap.class).getType(ast));
		parameterizedType.typeArguments().add(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(String.class).getType(ast));
		parameterizedType.typeArguments().add(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(String.class).getType(ast));
		VariableDeclarationStatement variableDeclarationStatement = ast.newVariableDeclarationStatement(variableDeclarationFragment);
		variableDeclarationStatement.setType(parameterizedType);
		statements.add(variableDeclarationStatement);
	}

	private static void addSetMappingItemsStatements(AST ast, ArrayList<Statement> statements, AssociationInfo associationInfo, String varMapping) {
		for (Map.Entry<String, String> item : associationInfo.getRefColumns().entrySet()) {
			if (associationInfo.getTargetColumn().equals(item.getValue())) {
				continue;
			}

			MethodInvocation methodInvocation = ast.newMethodInvocation();
			methodInvocation.setExpression(ast.newSimpleName(varMapping));
			methodInvocation.setName(ast.newSimpleName("put"));
			methodInvocation.arguments().add(GeneratorUtil.getStringLiteral(ast, item.getValue()));
			methodInvocation.arguments().add(GeneratorUtil.getStringLiteral(ast, item.getKey()));
			statements.add(ast.newExpressionStatement(methodInvocation));
		}

		{
			MethodInvocation methodInvocation = ast.newMethodInvocation();
			methodInvocation.setExpression(ast.newSimpleName(varMapping));
			methodInvocation.setName(ast.newSimpleName("put"));
			methodInvocation.arguments().add(GeneratorUtil.getStringLiteral(ast, associationInfo.getTargetColumn()));
			methodInvocation.arguments().add(GeneratorUtil.getStringLiteral(ast, associationInfo.getSourceColumn()));
			statements.add(ast.newExpressionStatement(methodInvocation));

//			((DataTypeAdapter)associationInfo.getRefRepository().getMainDac().getAdaptor()).
		}
	}

	//	CefMappingReader readerName = new CefMappingReader(mapping, reader);
	public static void addNewMappingReaderStatement(AST ast, ArrayList<Statement> statements, String readerName, String mappingName) {
		VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
		variableDeclarationFragment.setName(ast.newSimpleName(readerName));

		ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
		classInstanceCreation.setType(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(CefMappingReader.class).getType(ast));
		ArrayList arguments = new ArrayList();
		arguments.add(RepositoryGenUtil.createVariableLiteral(ast, mappingName));
		arguments.add(RepositoryGenUtil.createVariableLiteral(ast, ParamReader));
		classInstanceCreation.arguments().addAll(arguments);
		variableDeclarationFragment.setInitializer(classInstanceCreation);

		VariableDeclarationStatement variableDeclarationStatement = ast.newVariableDeclarationStatement(variableDeclarationFragment);
		variableDeclarationStatement.setType(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(CefMappingReader.class).getType(ast));
		statements.add(variableDeclarationStatement);
	}

	//	EntityRelationalAdaptor adapter=( (BaseRootRepository)( getAssociation("DeptID").RefRepository )).getEntityDac("").getEntityAdaptor();
	public static void addNewAdapterStatement(
			AST ast,
			ArrayList<Statement> statements,
			String propertyName,
			String adaperName,
			String nodeCode) {
		VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
		variableDeclarationFragment.setName(ast.newSimpleName(adaperName));
		addNewAdapterAdapterVarInitializer(ast, variableDeclarationFragment, propertyName, nodeCode);

		VariableDeclarationStatement variableDeclarationStatement = ast.newVariableDeclarationStatement(variableDeclarationFragment);
		variableDeclarationStatement.setType(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(EntityRelationalAdaptor.class).getType(ast));

		statements.add(variableDeclarationStatement);

	}

	private static void addNewAdapterAdapterVarInitializer(
			AST ast,
			VariableDeclarationFragment variableDeclarationFragment,
			String propertyName,
			String nodeCode) {
		MethodInvocation methodInvocation = ast.newMethodInvocation();
		methodInvocation.setName(ast.newSimpleName("getEntityAdaptor"));
		addgetEntityAdapterExpression(ast, methodInvocation, propertyName, nodeCode);
		variableDeclarationFragment.setInitializer(methodInvocation);
	}

	private static void addgetEntityAdapterExpression(AST ast, MethodInvocation methodInvocation, String propertyName, String nodeCode) {
		MethodInvocation methodInvocationGetDac = ast.newMethodInvocation();
		methodInvocationGetDac.setName(ast.newSimpleName("getEntityDac"));
		methodInvocationGetDac.arguments().add(GeneratorUtil.getStringLiteral(ast, nodeCode));
		addgetEntityDacExpression(ast, methodInvocationGetDac, propertyName);

		methodInvocation.setExpression(methodInvocationGetDac);

	}

	private static void addgetEntityDacExpression(AST ast, MethodInvocation methodInvocationGetDac, String propertyName) {
		CastExpression castExpression = ast.newCastExpression();
		castExpression.setType(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(BaseRootRepository.class).getType(ast));
		addgetRefRepositoryMethod(ast, castExpression, propertyName);

		ParenthesizedExpression parenthesizedExpression = ast.newParenthesizedExpression();
		parenthesizedExpression.setExpression(castExpression);
		methodInvocationGetDac.setExpression(parenthesizedExpression);
	}

	private static void addgetRefRepositoryMethod(AST ast, CastExpression castExpression, String propertyName) {
		MethodInvocation methodInvocation = ast.newMethodInvocation();
		methodInvocation.setName(ast.newSimpleName("getRefRepository"));

		MethodInvocation methodInvocationGetAssociation = ast.newMethodInvocation();
		methodInvocationGetAssociation.setName(ast.newSimpleName("getAssociation"));
		methodInvocationGetAssociation.arguments().add(GeneratorUtil.getStringLiteral(ast, propertyName));

		methodInvocation.setExpression(methodInvocationGetAssociation);
		castExpression.setExpression(methodInvocation);
	}

	public void addSetInfoPropertyStatemens(AST ast, ArrayList<Statement> statements, GspAssociation associationInfo, IGspCommonField gspCommonField, String propertyClassName, String propertyName, IGspCommonDataType gspCommonDataType, CefGeneratorContext cefGeneratorContext) {
//		for (Method method : propertyType.getMethods()) {
//			PropertyGetAtrribute propertyGetAtrribute = (PropertyGetAtrribute) ReflectionUtils.getMethodAnnotation(method, PropertyGetAtrribute.class);
//			if (propertyGetAtrribute == null)
//				continue;
//		    AssociationInfo ass = EntityGetAssocationDBMappingMethodGenerator.getAssociationInfo(cefGeneratorContext, associationInfo, gspCommonObject);
			addSetInfoPropertyStatement(ast, statements, propertyName, associationInfo, gspCommonField, propertyClassName, gspCommonDataType, cefGeneratorContext);
			for(IGspCommonField field:associationInfo.getRefElementCollection()){
				addSetInfoPropertyStatement(ast, statements, propertyName, associationInfo, field, propertyClassName, gspCommonDataType, cefGeneratorContext);
			}
//			BuildPropAssStatement(statements, associationInfo, refProp, propertyName);
//		}
	}


	private void addSetInfoPropertyStatement(AST ast, ArrayList<Statement> statements, String propertyName, GspAssociation associationInfo, IGspCommonField gspCommonField, String propertyClassName, IGspCommonDataType gspCommonDataType, CefGeneratorContext cefGeneratorContext) {
		MethodInvocation methodInvocation = ast.newMethodInvocation();
		methodInvocation.setName(ast.newSimpleName("set" + gspCommonField.getLabelID()));
		methodInvocation.setExpression(ast.newSimpleName(varName));
		addSetInfoPropertySetPropertyArguments(ast, methodInvocation, propertyName, associationInfo,gspCommonField, gspCommonDataType, cefGeneratorContext);

		statements.add(ast.newExpressionStatement(methodInvocation));
	}

	private void addSetInfoPropertySetPropertyArguments(AST ast, MethodInvocation methodInvocation, String propertyName, GspAssociation associationInfo, IGspCommonField gspCommonField, IGspCommonDataType gspCommonDataType, CefGeneratorContext cefGeneratorContext) {
		CastExpression castExpression=ast.newCastExpression();

		MethodInvocation methodInvocation1 = ast.newMethodInvocation();
		methodInvocation1.setName(ast.newSimpleName("readProperty"));
		methodInvocation1.setExpression(ast.newSimpleName("adapter"));
		RefAssociationInfo refAssociationInfo = getRefAssociation(gspCommonField, associationInfo);
		String refColumnName = getRefColumn(cefGeneratorContext, propertyName, associationInfo, gspCommonField, gspCommonDataType);
		if(refColumnName.isEmpty()){
			refColumnName = refAssociationInfo.getField().getLabelID();
		}
//		methodInvocation1.arguments().add(GeneratorUtil.getStringLiteral(ast, getRefColumn(cefGeneratorContext, propertyName, associationInfo, gspCommonField, gspCommonDataType)));
		methodInvocation1.arguments().add(GeneratorUtil.getStringLiteral(ast, refColumnName));
		methodInvocation1.arguments().add(ast.newSimpleName(getMappingReader(propertyName)));

		castExpression.setExpression(methodInvocation1);

		TypeInfo returnTypeInfo = null;
		if(gspCommonField.getLabelID().equals(propertyName)){
			returnTypeInfo = getEntityContext(cefGeneratorContext).getFieldTypeInfo(associationInfo.getRefObjectCode(), getAssoField(cefGeneratorContext, associationInfo));
		}
		else {

			if(gspCommonField.getObjectType() == GspElementObjectType.Enum){
//				IGspCommonField refField = getRefField(cefGeneratorContext, associationInfo, gspCommonField.getRefElementId());
				returnTypeInfo = Utils.getRefEnumElementType(refAssociationInfo.getField(), refAssociationInfo.getGspAssociation(), cefGeneratorContext);
			}
			else if(gspCommonField.getObjectType() == GspElementObjectType.Association) {

//				returnTypeInfo = getEntityContext(cefGeneratorContext).getAssoFieldTypeInfo(gspCommonField);
//				IGspCommonField refField = Utils.getRefField(gspCommonField, associationInfo, cefGeneratorContext);
				returnTypeInfo = Utils.getRefElementPropertyName(refAssociationInfo.getField(), refAssociationInfo.getGspAssociation(), cefGeneratorContext);
			}
			else {
				returnTypeInfo = Utils.getRefElementPropertyName(refAssociationInfo.getField(), refAssociationInfo.getGspAssociation(), cefGeneratorContext);
//				returnTypeInfo = getEntityContext(cefGeneratorContext).getFieldTypeInfo(refAssociationInfo.getGspAssociation().getRefObjectCode(), refAssociationInfo.getRefField());
			}
		}
		returnTypeInfo.addImport(cefGeneratorContext.getCoreGenContext());
//		TypeInfo returnTypeInfo = new TypeInfo(propertyClassName);
//		returnTypeInfo.setUseFullName(true);
		castExpression.setType(returnTypeInfo.getType(ast));
		methodInvocation.arguments().add(castExpression);
	}

	private RefAssociationInfo getRefAssociation(IGspCommonField field, GspAssociation gspAssociation){
		RefAssociationInfo refAssociationInfo = new RefAssociationInfo();
		GspAssociation refAssociation = null;
		GspMetadata metadata = cefGeneratorContext.getMetadataJitContext().
				getMetadata(gspAssociation.getRefModelID());
		GspBusinessEntity gspBusinessEntity = (GspBusinessEntity)metadata.getContent();
		IGspCommonObject refObject = gspBusinessEntity.findObjectById(gspAssociation.getRefObjectID());
		for(IGspCommonField commonField: refObject.getContainElements()){
			if(commonField.getID().equals(field.getRefElementId())){
				refAssociationInfo.setRefField(commonField);
				refAssociationInfo.setField(field);
				refAssociationInfo.setGspAssociation(gspAssociation);
				return refAssociationInfo;
			}
		}
		//说明是关联带出关联字段
		IGspCommonField tempField = null;
		tempField = refObject.findElement(field.getRefElementId());
		if(tempField != null){
			refAssociationInfo = getRefAssociation(tempField);
			if(refAssociation !=null && refAssociationInfo.getGspAssociation() != null){
				return refAssociationInfo;
			}
		}
		return refAssociationInfo;
	}

	private RefAssociationInfo getRefAssociation(IGspCommonField refElementField){
		RefAssociationInfo refAssociationInfo = new RefAssociationInfo();
		GspAssociation gspAssociation = refElementField.getParentAssociation();
		if(gspAssociation!= null){
			GspMetadata metadata = cefGeneratorContext.getMetadataJitContext().
					getMetadata(gspAssociation.getRefModelID());
			GspBusinessEntity gspBusinessEntity = (GspBusinessEntity)metadata.getContent();
			IGspCommonObject refObject = gspBusinessEntity.findObjectById(gspAssociation.getRefObjectID());
			for(IGspCommonField field: refObject.getContainElements()){
				if(field.getID().equals(refElementField.getRefElementId())){
					refAssociationInfo.setRefField(field);
					refAssociationInfo.setGspAssociation(gspAssociation);
					refAssociationInfo.setField(refElementField);
					return refAssociationInfo;
				}
			}
			IGspCommonField tempField = refObject.findElement(refElementField.getRefElementId());
			refAssociationInfo = getRefAssociation(tempField);
			if(refAssociationInfo.getGspAssociation() != null)
				return refAssociationInfo;
		}
		return refAssociationInfo;
	}

	private static EntityGeneratorContext getEntityContext(CefGeneratorContext cefGeneratorContext){
		return cefGeneratorContext.getCefCoreGenCtx().getEntityGeneratorContext();
	}


	private static IGspCommonField getAssoField(CefGeneratorContext cefGeneratorContext, GspAssociation associationInfo){
		String sourceElementId = "";
		IGspCommonObject refObject = getRefObject(cefGeneratorContext, associationInfo);
		for(GspAssociationKey key: associationInfo.getKeyCollection()){
			sourceElementId = key.getSourceElement();
			break;
		}
		for(IGspCommonField gspCommonField: refObject.getContainElements()){
			if(gspCommonField.getID().equals(sourceElementId)){
				return gspCommonField;
			}
		}
		return null;
	}

	public static String getRefColumn(CefGeneratorContext cefGeneratorContext, String souceName, GspAssociation associationInfo,
									  IGspCommonField commonField, IGspCommonDataType gspCommonDataType) {
		String sourceElementId = "";
		String targetElementId = "";
		String sourceColumn = "";
		String targetColumn = "";
		for(GspAssociationKey key: associationInfo.getKeyCollection()){
			sourceElementId = key.getSourceElement();
			targetElementId = key.getTargetElement();
		}
		for(IGspCommonField gspCommonField: gspCommonDataType.getContainElements()){
			if(gspCommonField.getID().equals(targetElementId)){
				targetColumn = gspCommonField.getLabelID();
				break;
			}
		}

		//获取target

		IGspCommonObject refObject = getRefObject (cefGeneratorContext, associationInfo);
		for(IGspCommonField refField:refObject.getContainElements()){
			if(refField.getID().equals(sourceElementId)){
				sourceColumn = refField.getLabelID();
				break;
			}
		}
		if (targetElementId.equals(commonField.getID())) {
			return sourceColumn;
		}
		IGspCommonField refField = refObject.findElement(commonField.getRefElementId());
		if(refField != null){
			return refField.getLabelID();
		}
		return "";
	}

	private static IGspCommonObject getRefObject(CefGeneratorContext cefGeneratorContext, GspAssociation gspAssociation){
		GspMetadata metadata = cefGeneratorContext.getMetadataJitContext().
				getMetadata(gspAssociation.getRefModelID());
		GspBusinessEntity gspBusinessEntity = (GspBusinessEntity) metadata.getContent();
		IGspCommonObject refObject = (IGspCommonObject) gspBusinessEntity.findObjectById(gspAssociation.getRefObjectID());
		return refObject;
	}
	private static IGspCommonField getRefField(CefGeneratorContext cefGeneratorContext, GspAssociation gspAssociation, String elementId){
		IGspCommonField refField = null;
		IGspCommonObject gspCommonObject = getRefObject(cefGeneratorContext, gspAssociation);
		for(IGspCommonField field:gspCommonObject.getContainElements()){
			if(field.getID().equals(elementId)) {
				refField = field;
				break;
			}
		}
		return refField;
	}

	public static String getMappingReader(String propertyName) {
		return "mappingReader" + propertyName;
	}


	public static String getAssPropertyValueMethodName(String propertyName) {
		return "get" + propertyName + "AssPropertyValue";
	}

}
